/**
* Description: 表格组件
*
* Created by hrx on 2023/8/10
*/
<template>
  <div class="table-component">
    <div class="table-content">
      <el-table
        ref="table"
        :data="dataSource"
        :border="border"
        style="width: 100%"
        :row-style="rowStyle"
        @row-click="onRowClick"
        @sort-change="onSortChange"
        @select-all="onSelectAll"
        @selection-change="onSelectionChange"
        :empty-text="emptyText"
        :row-key="rowKey"
        :height="lengthUnit(height)"
        :max-height="lengthUnit(maxHeight)"
        @header-dragend="headerDragend"
      >
        <template slot="empty">
          <img style="width: 200px; height: 250px"
               :src="notDataImg"
               alt=""
          />
        </template>
        <el-table-column
          :key="item.prop + index" v-for="(item, index) in tableTitlesData"
          :label="item.label"
          :prop="item.prop"
          :width="item.width"
          :min-width="item.minWidth"
          :align="item.align"
          :type="item.type"
          :fixed="item.fixed"
          :sortable="item.sortable"
          :show-overflow-tooltip="item.tooltip"
          :reserve-selection="item.reserveSelection"
          :selectable="item.selectable"
        >
          <template v-if="item.tips" #header="scope">
            {{scope.column.label}}
            <el-tooltip effect="dark" placement="top">
              <div slot="content">
                {{item.tips}}
              </div>
              <i class="el-icon-question"></i>
            </el-tooltip>
          </template>
          <template v-else-if="item.header" #header="scope">
            <slot :name="item.headerProp" :row="scope.column" :index="scope.$index"></slot>
          </template>
          <template v-if="item.template" #default="scope">
            <slot :name="item.prop" :row="scope.row" :index="scope.$index"></slot>
          </template>
          <template v-else-if="item.type != 'selection'" #default="scope">
            {{ computedText(scope.row[item.prop]) }}
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pagination" v-if="pagination">
      <el-pagination
        background
        @size-change="handlePageSizeChange"
        @current-change="handlePageChange"
        :current-page.sync="ppage"
        :page-sizes="pageNumberList"
        :page-size="pnumber"
        :layout="paginationLayout"
        :total="total">
      </el-pagination>
    </div>
  </div>
</template>

<script>
import {lengthUnit} from '../../utils';

export default {
  name: "TableComponent",
  props: {
    tableData: {
      type: Array,
      default: function () {
        return [];
      }
    },

    rowKey: {
      type: String | Function,
      default: function () {
        return undefined;
      }
    },

    defaultPageNumber: {
      type: Number,
      default: 10
    },

    border: {
      type: Boolean,
      default: false
    },

    pageNumberList: {
      type: Array,
      default: function () {
        return [10, 20, 50, 100];
      }
    },

    tableTitles: {
      type: Array,
      default: function () {
        return [];
      }
    },

    pagination: {
      type: Boolean,
      default: true
    },


    paginationLayout: {
      type: String,
      default: function () {
        return "total, sizes, prev, pager, next, jumper";
      }
    },

    autoLoad: {
      type: Boolean,
      default: true
    },

    remoteApi: {
      type: Function,
      default: null
    },

    showTableTitleFilter: {
      type: Boolean,
      default: false
    },

    rowStyle: {
      type: Function,
      default: function () {
        return {height: '60px'};
      }
    },

    emptyText: {
      type: String,
      default: function () {
        return '暂无数据';
      }
    },

    emptyDataText: {
      type: String,
      default: function () {
        return '';
      }
    },

    ppageText: {
      type: String,
      default: function () {
        return 'page';
      }
    },

    pnumberText: {
      type: String,
      default: function () {
        return 'limit';
      }
    },
    height: {
      type: [Number, String],
      default: '640px'
    },
    maxHeight: {
      type: [Number, String],
      default: undefined
    },
    returnScrollTop: {
      type: Boolean,
      default: false
    },
    notDataImg: {
      type: String,
      default: 'https://iotest.dictech.com.cn/image/wechat/train/notData.png'
    },
    localStoragePageNumber:{
      type: Boolean,
      default: false
    }
  },

  data() {
    const ppage = 1;
    const pnumber = this.getLocalStoragePageNumber();
    let dataSource = !this.remoteApi && this.tableData ? [...this.tableData] : [];
    if (this.pagination && dataSource.length > 0) {
      dataSource = dataSource.slice(0, this.getLocalStoragePageNumber());
    }
    const total = !this.remoteApi && this.tableData ? this.tableData.length : 0;
    const tableTitlesData = this.tableTitles;
    const openColumns = this.tableTitles.map(item => item.prop);
    return {
      lengthUnit,
      dataSource,
      total,
      ppage,
      pnumber,
      params: undefined,
      tableTitlesData,
      openColumns,
      pdirection: undefined,
      pcolumn: undefined
    };
  },

  computed: {
    computedText() {
      return function (text) {
        let res = text;
        if (text === undefined || text === null || text === '') {
          res = this.emptyDataText;
        }
        return res;
      };
    }
  },

  watch: {
    tableData: {
      handler(newVal) {
        let data = !this.remoteApi && newVal ? [...newVal] : [];
        if (this.pagination && newVal.length > 0) {
          data = newVal.slice((this.ppage - 1) * this.pnumber, this.ppage * this.pnumber);
          if (data.length === 0 && this.ppage - 1 > 0) {
            data = newVal.slice((this.ppage - 2) * this.pnumber, (this.ppage - 1) * this.pnumber);
          }
        }
        this.dataSource = data;
        this.total = !this.remoteApi && newVal ? newVal.length : 0;
      },
      deep: true
    },

    tableTitles: {
      handler(newVal) {
        this.tableTitlesData = newVal;
        this.$nextTick(_ => {
          this.$refs.table.doLayout();
        });
      }
    },
    dataSource: {
      handler(newVal) {
        this.$emit('onDataChange', newVal);
        this.$emit('on-data-change', newVal);
      },
      deep: true
    }
  },

  mounted() {
    this.autoLoad && this.queryData();
  },


  methods: {
    queryData(queryParams) {

      this.getDataSourceFormServer(queryParams);
    },

    refreshData(queryParams) {
      this.ppage = 1;
      // this.pnumber = this.defaultPageNumber;
      this.$refs.table.clearSort()
      this.getDataSourceFormServer(queryParams);
    },

    async getDataSourceFormServer(params) {
      if (!this.remoteApi) {
        return;
      }
      this.params = params;
      const p = {
        [this.ppageText]: this.pagination ? this.ppage : undefined,
        [this.pnumberText]: this.pagination ? this.pnumber : undefined,
        pdirection: this.pdirection,
        pcolumn: this.pcolumn,
        ...this.params
      };
      const data = await this.remoteApi(p);
      if (data) {
        this.dataSource = data.data.data.list;
        this.total = data.data.data.totalCount;
        this.$emit('onLoaded', data);
        this.$emit('on-loaded', data);
        this.$refs.table.doLayout();
        if (this.returnScrollTop && this.$refs.table.bodyWrapper.scrollTop != 0) this.$refs.table.bodyWrapper.scrollTop = 0;
      }
    },

    handlePageChange(ppage) {
      this.ppage = ppage;
      if (this.remoteApi) {
        this.getDataSourceFormServer(this.params);
      } else {
        this.dataSource = this.tableData ? this.tableData.slice((ppage - 1) * this.pnumber, ppage * this.pnumber) : [];
        if (this.returnScrollTop && this.$refs.table.bodyWrapper.scrollTop != 0) this.$refs.table.bodyWrapper.scrollTop = 0;
      }
    },

    handlePageSizeChange(pnumber) {
      if(this.localStoragePageNumber) window.localStorage.setItem('localStoragePageNumber', pnumber)
      this.ppage = 1;
      this.pnumber = pnumber;
      if (this.remoteApi) {
        this.getDataSourceFormServer(this.params);
      } else {
        this.dataSource = this.tableData ? this.tableData.slice(0, pnumber) : [];
        if (this.returnScrollTop && this.$refs.table.bodyWrapper.scrollTop != 0) this.$refs.table.bodyWrapper.scrollTop = 0;
      }
    },

    getDataSource() {
      return this.dataSource;
    },

    getTotal() {
      return this.total;
    },

    getPageNumber() {
      return this.ppage;
    },

    getPageSize() {
      return this.pnumber;
    },

    onRowClick(row) {
      this.$emit('onRowClick', row);
      this.$emit('on-row-click', row);
    },

    onSelectAll(val) {
      this.$emit('onSelectAll', val);
      this.$emit('on-select-all', val);
    },

    onSelectionChange(val) {
      this.$emit('onSelectionChange', val);
      this.$emit('on-selection-change', val);
    },

    clearSelection() {
      this.$refs.table.clearSelection();
    },

    toggleRowSelection(row, val) {
      this.$refs.table.toggleRowSelection(row, val);
    },

    onSortChange({prop, order}) {
      this.$emit('sortChange', prop, order);
      this.$emit('sort-change', prop, order);

      // this.pcolumn = order === null ? undefined : prop;
      // this.pdirection = order === null ? undefined : order === 'ascending';
      // this.getDataSourceFormServer(this.params);
    },
    headerDragend(newWidth, oldWidth, column, event){
      if(column.label == '序号' || column.label == '操作') column.width = oldWidth;
      this.$emit("headerDragend",{newWidth, oldWidth, column, event})
      this.$emit("header-dragend",{newWidth, oldWidth, column, event})
    },
    refreshSelection(selection = []) {
      this.clearSelection();
      selection.forEach(row => {
        if (row) {
          this.toggleRowSelection(row, true);
        }
      });
    },
    getLocalStoragePageNumber(){
      if(this.localStoragePageNumber){
        return localStorage.getItem('localStoragePageNumber') ? Number(localStorage.getItem('localStoragePageNumber')) : this.defaultPageNumber
      } else {
        return this.defaultPageNumber
      }
    }
  }
};
</script>

<style lang='less' scoped>
.table-component {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  /deep/ .el-table__header {
    width: 100% !important;
  }
  /deep/ .el-table__empty-block {
    width: 100% !important;
  }
  /deep/ .el-table__body {
    width: 100% !important;
  }
  .table-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: auto;
  }

  /deep/ .pagination {
    display: flex;
    justify-content: flex-end;
    float: right;
    padding: 16px 20px 9px 20px;
    align-items: center;
    color: #252631;
  }
}
</style>
